<?php
namespace App\Services;

use App\Models\UserModel;
use App\Services\HttpService;
use Carbon\Carbon;
use Framework\BaseService;
use Framework\Hope;
use Framework\ModelEncryptionTrait;

class SmsService extends BaseService
{
    use ModelEncryptionTrait;
    /** 发送短信验证码
     * @param string $phone
     * @param string $type
     * @return bool
     * @throws \AlibabaCloud\Client\Exception\ClientException
     */
    public function sendSmsVerifyCode(string $phone,string $type)
    {

        if(!Hope::isProduct()){
            return true;
        }

        if(!Hope::validatePhone($phone)){
            $this->retError('请输入正确的手机号');
        }

        if(!$type){
            $this->retError("缺少类型");
        }

        $redis = Hope::getRedis();

        $key = $this->getKey($phone);
        $limitKey = 'code_limit';

        // 验证码重发限制
        $jsonData = $redis->get($key);
        $data = $jsonData ? json_decode($jsonData, true) : [];
        if ($data && Carbon::now()->timestamp < $data['resend_expire']) {
            $this->retError( '短信已在1分钟内发出，请耐心等');
        }
        // 手机号限制
        $sendCnt = $redis->zScore($limitKey, $phone);
        if ($sendCnt && $sendCnt >= config('sms.one_day_freq', 5)) {
            $this->retError("获取验证码次数已达上限");
        }

        //生成4位验证码
        $code = $this->createVerifyCode($phone);

        //发送短信获取验证码
//        app(HttpService::class)->sendSms($phone,$code);
        //更换为腾讯短信
        app(HttpService::class)->TencentsendSms($phone,$code,$type);
        //redis中存储验证码
        $this->saveSmsCode($phone, $code, $key, $limitKey);
        return  true;
    }

    public function saveSmsCode(string $phone, string $code, string $key, string $limitKey)
    {
        $redis = Hope::getRedis();
        $data = [
            'code' => $code,
            'resend_expire' => Carbon::now()->addSeconds(config('sms.resend_sec', 60))->timestamp,
        ];
        $redis->set($key, json_encode($data));
        $redis->expire($key, (int) config('sms.expire_sec', 1800) ); // 设置验证码过期时间

        // 设置手机号限制
        $redis->zIncrBy($limitKey, 1, $phone);
        $redis->expireAt($limitKey, (int) Carbon::today()->addDay()->timestamp);
        if (! Hope::isProduct()) {
            return true;
        }
    }

    /**
     * 验证短信验证码
     * @param string $phone 手机号
     * @param string $code  验证码
     * @return bool
     */
    public function checkSmsCode(string $phone, string $code): bool
    {
        $testSmsCode = config('constant.sms_code');
        if (config('app.env','dev') != 'prod' && $code == $testSmsCode) {
            return true;
        }

        $arr = [$testSmsCode, $this->createVerifyCode($phone)];
        if (!Hope::isProduct() && in_array($code, $arr )) {
            return true;
        }


        $key = $this->getKey($phone);
        $jsonData = Hope::getRedis()->get($key);
        $data = $jsonData ? json_decode($jsonData, true) : [];
        if ($data && $code === $data['code']) {
            return true;
        }
        $this->retError("验证码有误，请重新输入！");
    }

    /**
     * @param string $phone 手机号
     * @return string
     */
    private function getKey(string $phone): string
    {
        return "code:" . $phone;
    }

    /**
     * 创建4位验证码
     * @param string $phone 手机号
     * @return string
     */
    private function createVerifyCode(string $phone): string
    {
        if(!Hope::isProduct()){
            return substr($phone, -4);
        }
        return (string)mt_rand(1000, 9999);
    }
}
